#include <wx/wx.h>
#include "panel_wah.h"
#include "MyCommon.h"
#include "DataSave.h"

#define SLI_MAX(max,min,step) (int)((max - min) / step)


wxDEFINE_EVENT(myEVT_WAH, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_SPEED, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_FILTER_Q, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_FILTER_GAIN, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_FILTER_FREQ_CENTER, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_FILTER_FREQ_WIDTH, MyEventWah);
wxDEFINE_EVENT(myEVT_WAH_ENABLE, MyEventWah);


// wxBEGIN_EVENT_TABLE(PanelWah, wxPanel)
//     EVT_SLIDER(PanelWah::ID_SLI_FILTER_FREQ_WIDTH, PanelWah::OnSliderChange)
//     EVT_SLIDER(PanelWah::ID_SLI_SPEED, PanelWah::OnSliderChange)
//     EVT_SLIDER(PanelWah::ID_SLI_FILTER_Q, PanelWah::OnSliderChange)
//     EVT_SLIDER(PanelWah::ID_SLI_FILTER_FREQ_CENTER, PanelWah::OnSliderChange)
//     EVT_TEXT_ENTER(PanelWah::ID_TXT_FILTER_FREQ_WIDTH,PanelWah::OnTextEnter)
//     EVT_TEXT_ENTER(PanelWah::ID_TXT_SPEED,PanelWah::OnTextEnter)
//     EVT_TEXT_ENTER(PanelWah::ID_TXT_FILTER_Q,PanelWah::OnTextEnter)
//     EVT_TEXT_ENTER(PanelWah::ID_TXT_FILTER_FREQ_CENTER,PanelWah::OnTextEnter)
//     EVT_CHECKBOX(PanelWah::ID_CHK_SWITCH,PanelWah::OnChkChange)
// wxEND_EVENT_TABLE()


PanelWah::PanelWah(const wxString &title, wxXmlNode *node, wxWindowID id, wxWindow *parent)
    : wxPanel(parent,id,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL)
{
    SetSize(200, 300);

    root_node = node;
    select_index = 0;

    wxWindowID cid = id + 1;
    ID_TXT_FILTER_FREQ_WIDTH = cid++;
    ID_TXT_SPEED = cid++;
    ID_TXT_FILTER_Q = cid++;
    ID_TXT_FILTER_GAIN = cid++;
    ID_TXT_FILTER_FREQ_CENTER = cid++;
    ID_SLI_FILTER_FREQ_WIDTH = cid++;
    ID_SLI_SPEED = cid++;
    ID_SLI_FILTER_Q = cid++;
    ID_SLI_FILTER_GAIN = cid++;
    ID_SLI_FILTER_FREQ_CENTER = cid++;
    ID_CHK_SWITCH = cid++;
    ID_CHO_PRESET = cid ++;

    wxCheckBox      *chk_enable            = new wxCheckBox(this,   ID_CHK_SWITCH,            "Enable");
    wxTextCtrl      *txt_speed             = new wxTextCtrl(this,   ID_TXT_SPEED,             mDoubleToString(speed_min),             wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_filter_q          = new wxTextCtrl(this,   ID_TXT_FILTER_Q,          mDoubleToString(filter_q_min),          wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_filter_gain       = new wxTextCtrl(this,   ID_TXT_FILTER_GAIN,       mDoubleToString(filter_gain_min),       wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_filter_freq_center = new wxTextCtrl(this,   ID_TXT_FILTER_FREQ_CENTER, mDoubleToString(filter_freq_center_min), wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxTextCtrl      *txt_filter_freq_width   = new wxTextCtrl(this,   ID_TXT_FILTER_FREQ_WIDTH,   mDoubleToString(filter_freq_width_min),   wxDefaultPosition, wxDefaultSize,                 wxTE_PROCESS_ENTER);
    wxStaticText    *lab_speed             = new wxStaticText(this, wxID_ANY,                 "Speed:");
    wxStaticText    *lab_filter_q          = new wxStaticText(this, wxID_ANY,                 "FilterQ:");
    wxStaticText    *lab_filter_gain       = new wxStaticText(this, wxID_ANY,                 "FilterGain:");
    wxStaticText    *lab_filter_freq_center = new wxStaticText(this, wxID_ANY,                 "FilterFreqCenter(Hz):");
    wxStaticText    *lab_filter_freq_width   = new wxStaticText(this, wxID_ANY,                 "FilterFreqWidth(Hz):");
    wxStaticText    *lab_preset            = new wxStaticText(this, wxID_ANY,                 "Preset:");
    wxSlider        *sli_filter_freq_width   = new wxSlider(this,     ID_SLI_FILTER_FREQ_WIDTH,   0,                                      0,                 SLI_MAX(filter_freq_width_max,   filter_freq_width_min,   filter_freq_width_step));
    wxSlider        *sli_speed             = new wxSlider(this,     ID_SLI_SPEED,             0,                                      0,                 SLI_MAX(speed_max,             speed_min,             speed_step));
    wxSlider        *sli_filter_q          = new wxSlider(this,     ID_SLI_FILTER_Q,          0,                                      0,                 SLI_MAX(filter_q_max,          filter_q_min,          filter_q_step));
    wxSlider        *sli_filter_gain       = new wxSlider(this,     ID_SLI_FILTER_GAIN,       0,                                      0,                 SLI_MAX(filter_gain_max,       filter_gain_min,       filter_gain_step));
    wxSlider        *sli_filter_freq_center = new wxSlider(this,     ID_SLI_FILTER_FREQ_CENTER, 0,                                      0,                 SLI_MAX(filter_freq_center_max, filter_freq_center_min, filter_freq_center_step));
    wxFlexGridSizer *layout_main           = new wxFlexGridSizer(7, 3,                        wxSize(3,                               3));
    wxChoice        *cho_preset            = new wxChoice(this,     ID_CHO_PRESET);

    sli_filter_freq_width->SetMinSize(wxSize(100, -1));
    sli_filter_freq_width->SetTick(1);
    sli_speed->SetMinSize(wxSize(100, -1));
    sli_filter_q->SetMinSize(wxSize(100, -1));
    sli_filter_gain->SetMinSize(wxSize(100, -1));
    sli_filter_freq_center->SetMinSize(wxSize(100, -1));
    txt_filter_freq_width->SetMinSize(wxSize(50, -1));
    txt_filter_freq_width->SetMaxSize(wxSize(100, -1));
    txt_speed->SetMinSize(wxSize(50, -1));
    txt_speed->SetMaxSize(wxSize(100, -1));
    txt_filter_q->SetMinSize(wxSize(50, -1));
    txt_filter_q->SetMaxSize(wxSize(100, -1));
    txt_filter_gain->SetMinSize(wxSize(50, -1));
    txt_filter_gain->SetMaxSize(wxSize(100, -1));
    txt_filter_freq_center->SetMinSize(wxSize(50, -1));
    txt_filter_freq_center->SetMaxSize(wxSize(100, -1));

    sli_filter_q->Bind(wxEVT_SLIDER, &PanelWah::OnSliderChange, this, ID_SLI_FILTER_Q);
    sli_filter_gain->Bind(wxEVT_SLIDER, &PanelWah::OnSliderChange, this, ID_SLI_FILTER_GAIN);
    sli_filter_freq_width->Bind(wxEVT_SLIDER, &PanelWah::OnSliderChange, this, ID_SLI_FILTER_FREQ_WIDTH);
    sli_speed->Bind(wxEVT_SLIDER, &PanelWah::OnSliderChange, this, ID_SLI_SPEED);
    sli_filter_freq_center->Bind(wxEVT_SLIDER, &PanelWah::OnSliderChange, this, ID_SLI_FILTER_FREQ_CENTER);
    txt_filter_freq_width->Bind(wxEVT_TEXT_ENTER, &PanelWah::OnTextEnter, this, ID_TXT_FILTER_FREQ_WIDTH);
    txt_speed->Bind(wxEVT_TEXT_ENTER, &PanelWah::OnTextEnter, this, ID_TXT_SPEED);
    txt_filter_q->Bind(wxEVT_TEXT_ENTER, &PanelWah::OnTextEnter, this, ID_TXT_FILTER_Q);
    txt_filter_gain->Bind(wxEVT_TEXT_ENTER, &PanelWah::OnTextEnter, this, ID_TXT_FILTER_GAIN);
    txt_filter_freq_center->Bind(wxEVT_TEXT_ENTER, &PanelWah::OnTextEnter, this, ID_TXT_FILTER_FREQ_CENTER);
    chk_enable->Bind(wxEVT_CHECKBOX, &PanelWah::OnChkChange, this, ID_CHK_SWITCH);
    cho_preset->Bind(wxEVT_CHOICE,        &PanelWah::OnCombChange,   this, ID_CHO_PRESET);

    // cho_preset->Append("wah-1");
    // cho_preset->Append("wah-2");
    // cho_preset->Append("wah-3");
    // cho_preset->Append("wah-4");
    // cho_preset->Append("wah-5");
    // cho_preset->Append("wah-6");
    // cho_preset->Select(select_index);


    layout_main->Add(chk_enable  ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddStretchSpacer();
    layout_main->Add(lab_speed     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_speed     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_speed     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_filter_q,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_filter_q,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_filter_q,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_filter_gain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_filter_gain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_filter_gain,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_filter_freq_center    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_filter_freq_center    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_filter_freq_center    ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_filter_freq_width     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(txt_filter_freq_width     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(sli_filter_freq_width     ,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(lab_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->Add(cho_preset,0,wxALIGN_CENTER_VERTICAL | wxEXPAND);
    layout_main->AddStretchSpacer();
    layout_main->AddGrowableCol(0,0);
    layout_main->AddGrowableCol(1,0);
    layout_main->AddGrowableCol(2,1);

    SetSizer(layout_main);

    paneInfo.Caption(title);
    paneInfo.Dock();
    paneInfo.Dockable(true);
    paneInfo.CloseButton(true);
    paneInfo.MaximizeButton(true);
    paneInfo.MinimizeButton(true);
    paneInfo.DestroyOnClose(false);
    // paneInfo.Direction(wxLeft);

    param_event.SetEventObject(this);

    param.speed = speed_min;
    param.filter_q = filter_q_min;
    param.filter_gain = filter_gain_min;
    param.filter_freq_center = filter_freq_center_min;
    param.filter_freq_width = filter_freq_width_min;
    param.enable = false;

    // wxString str;
    // wxString select_name = attr_name_preset_default;
    // if(DataSave::NodeAttributesGetValue(root_node,attr_name_select,str))
    // {
    //     select_name = str;
    // }
    // else
    // {
    //     DataSave::NodeAttributesSetValue(root_node,attr_name_select,attr_name_preset_default);
    // }
    preset_node = nullptr;
    if(cho_preset->GetCount() > 0)
    {
        preset_node = SelectPreset(cho_preset->GetString(select_index));
    }
}


wxAuiPaneInfo &PanelWah::GetPaneInfo()
{
    return paneInfo;
}


void PanelWah::SetShow(bool show)
{
    Show(show);
}


void PanelWah::OnSliderChange(wxCommandEvent& event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_SLI_FILTER_FREQ_WIDTH)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_WIDTH),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_WIDTH),wxTextCtrl);
            double sv = sli->GetValue();
            double v = filter_freq_width_min + sv / (1/filter_freq_width_step);
            txt->SetValue(mDoubleToString(v));
            param.filter_freq_width = v;
            TrigerEvent(EV_FILTER_FREQ_WIDTH);
        }
        else if(id ==  ID_SLI_SPEED)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_SPEED),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_SPEED),wxTextCtrl);
            double sv = sli->GetValue();
            double v = speed_min + sv / (1/speed_step);
            txt->SetValue(mDoubleToString(v));
            param.speed = v;
            TrigerEvent(EV_SPEED);
        }
        else if(id ==  ID_SLI_FILTER_FREQ_CENTER)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_CENTER),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_CENTER),wxTextCtrl);
            double sv = sli->GetValue();
            double v = filter_freq_center_min + sv / (1/filter_freq_center_step);
            txt->SetValue(mDoubleToString(v));
            param.filter_freq_center = v;
            TrigerEvent(EV_FILTER_FREQ_CENTER);
        }
        else if(id ==  ID_SLI_FILTER_Q)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_Q),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_Q),wxTextCtrl);
            double sv = sli->GetValue();
            double v = filter_q_min + sv / (1/filter_q_step);
            txt->SetValue(mDoubleToString(v));
            param.filter_q = v;
            TrigerEvent(EV_FILTER_Q);
        }
        else if(id ==  ID_SLI_FILTER_GAIN)
        {
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_GAIN),wxSlider);
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_GAIN),wxTextCtrl);
            double sv = sli->GetValue();
            double v = filter_gain_min + sv / (1/filter_gain_step);
            txt->SetValue(mDoubleToString(v));
            param.filter_gain = v;
            TrigerEvent(EV_FILTER_GAIN);
        }
    }
}

void PanelWah::OnTextEnter(wxCommandEvent& event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_TXT_FILTER_FREQ_WIDTH)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_WIDTH),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= filter_freq_width_min) && (v <= filter_freq_width_max))
                {
                    param.filter_freq_width = v;
                }
            }
            double sv = (param.filter_freq_width - filter_freq_width_min) * (1/filter_freq_width_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_WIDTH),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_FILTER_FREQ_WIDTH);
        }
        else if(id ==  ID_TXT_SPEED)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_SPEED),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= speed_min) && (v <= speed_max))
                {
                    param.speed = v;
                }
            }
            double sv = (param.speed - speed_min) * (1/speed_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_SPEED),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_SPEED);
        }
        else if(id ==  ID_TXT_FILTER_FREQ_CENTER)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_CENTER),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= filter_freq_center_min) && (v <= filter_freq_center_max))
                {
                    param.filter_freq_center = v;
                }
            }
            double sv = (param.filter_freq_center - filter_freq_center_min) * (1/filter_freq_center_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_CENTER),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_FILTER_FREQ_CENTER);
        }
        else if(id ==  ID_TXT_FILTER_Q)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_Q),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= filter_q_min) && (v <= filter_q_max))
                {
                    param.filter_q = v;
                }
            }
            double sv = (param.filter_q - filter_q_min) * (1/filter_q_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_Q),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_FILTER_Q);
        }
        else if(id ==  ID_TXT_FILTER_GAIN)
        {
            wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_GAIN),wxTextCtrl);
            double v ;
            if(txt->GetValue().ToDouble(&v) == true)
            {
                if((v >= filter_gain_min) && (v <= filter_gain_max))
                {
                    param.filter_gain = v;
                }
            }
            double sv = (param.filter_gain - filter_gain_min) * (1/filter_gain_step);
            wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_GAIN),wxSlider);
            sli->SetValue(sv);
            TrigerEvent(EV_FILTER_GAIN);
        }
    }
}

void PanelWah::OnChkChange(wxCommandEvent &event)
{
    int id = event.GetId();
    // switch(id)
    {
        if(id == ID_CHK_SWITCH)
        {
            wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
            param.enable = chk->IsChecked();
            TrigerEvent(EV_ENABLE);
        }
    }
}

void PanelWah::OnCombChange(wxCommandEvent& event)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    int i = cmb->GetSelection();
    if((unsigned int)i < cmb->GetCount())
    {
        select_index = i;
        preset_node = SelectPreset(cmb->GetString(i));
        param_event.SetPresetIndex(select_index);
        param_event.SetEventType(myEVT_WAH);
        ProcessWindowEvent(param_event);
    }
}


double PanelWah::SetParamFilterFreqWidth(double v)
{
    if(v < filter_freq_width_min)
    {
        v = filter_freq_width_min;
    }
    else if(v > filter_freq_width_max)
    {
        v = filter_freq_width_max;
    }
    double sv = (v - filter_freq_width_min) * (1/filter_freq_width_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_WIDTH),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_WIDTH),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.filter_freq_width = v;
    param_event.SetFilterFreqWidth(v);
    return v;
}

double PanelWah::SetParamSpeed(double v)
{
    if(v < speed_min)
    {
        v = speed_min;
    }
    else if(v > speed_max)
    {
        v = speed_max;
    }
    double sv = (v - speed_min) * (1/speed_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_SPEED),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_SPEED),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.speed = v;
    param_event.SetSpeed(v);
    return v;
}

double PanelWah::SetParamFilterFreqCenter(double v)
{
    if(v < filter_freq_center_min)
    {
        v = filter_freq_center_min;
    }
    else if(v > filter_freq_center_max)
    {
        v = filter_freq_center_max;
    }
    double sv = (v - filter_freq_center_min) * (1/filter_freq_center_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_FREQ_CENTER),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_FREQ_CENTER),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.filter_freq_center = v;
    param_event.SetFilterFreqCenter(v);
    return v;
}

double PanelWah::SetParamFilterQ(double v)
{
    if(v < filter_q_min)
    {
        v = filter_q_min;
    }
    else if(v > filter_q_max)
    {
        v = filter_q_max;
    }
    double sv = (v - filter_q_min) * (1/filter_q_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_Q),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_Q),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.filter_q = v;
    param_event.SetFilterQ(v);
    return v;
}

double PanelWah::SetParamFilterGain(double v)
{
    if(v < filter_gain_min)
    {
        v = filter_gain_min;
    }
    else if(v > filter_gain_max)
    {
        v = filter_gain_max;
    }
    double sv = (v - filter_gain_min) * (1/filter_gain_step);
    wxSlider *sli = wxDynamicCast(FindWindowById(ID_SLI_FILTER_GAIN),wxSlider);
    sli->SetValue(sv);
    wxTextCtrl *txt = wxDynamicCast(FindWindowById(ID_TXT_FILTER_GAIN),wxTextCtrl);
    txt->SetValue(mDoubleToString(v));
    param.filter_gain = v;
    param_event.SetFilterGain(v);
    return v;
}

bool PanelWah::SetParamEnable(bool v)
{
    wxCheckBox *chk = wxDynamicCast(FindWindowById(ID_CHK_SWITCH),wxCheckBox);
    chk->SetValue(v);
    param.enable = v;
    param_event.SetEnable(v);
    return v;
}

double PanelWah::GetParamFilterFreqWidth() { return param.filter_freq_width; }
double PanelWah::GetParamSpeed() { return param.speed; }
double PanelWah::GetParamFilterQ() { return param.filter_q; }
double PanelWah::GetParamFilterGain() { return param.filter_gain; }
double PanelWah::GetParamFilterFreqCenter() { return param.filter_freq_center; }
bool PanelWah::GetParamEnable() { return param.enable; }


void PanelWah::SetPresetIndex(const unsigned int index)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(index < cmb->GetCount())
    {
        select_index = index;
        param_event.SetPresetIndex(select_index);
        cmb->SetSelection(index);
        preset_node = SelectPreset(cmb->GetString(index));
    }
}

int PanelWah::GetPresetIndex()
{
    return select_index;
}

void PanelWah::TrigerEvent(int ev)
{
    switch(ev)
    {
        case EV_FILTER_FREQ_WIDTH:
        {
            param_event.SetEventType(myEVT_WAH_FILTER_FREQ_WIDTH);
            param_event.SetFilterFreqWidth(param.filter_freq_width);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_filter_freq_width, mDoubleToString(param.filter_freq_width).c_str());
        }
        break;
        case EV_SPEED:
        {
            param_event.SetEventType(myEVT_WAH_SPEED);
            param_event.SetSpeed(param.speed);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_speed, mDoubleToString(param.speed).c_str());
        }
        break;
        case EV_FILTER_FREQ_CENTER:
        {
            param_event.SetEventType(myEVT_WAH_FILTER_FREQ_CENTER);
            param_event.SetFilterFreqCenter(param.filter_freq_center);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_filter_freq_center, mDoubleToString(param.filter_freq_center).c_str());
        }
        break;
        case EV_FILTER_Q:
        {
            param_event.SetEventType(myEVT_WAH_FILTER_Q);
            param_event.SetFilterQ(param.filter_q);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_filter_q, mDoubleToString(param.filter_q).c_str());
        }
        break;
        case EV_FILTER_GAIN:
        {
            param_event.SetEventType(myEVT_WAH_FILTER_GAIN);
            param_event.SetFilterGain(param.filter_gain);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_filter_gain, mDoubleToString(param.filter_gain).c_str());
        }
        break;
        case EV_ENABLE:
        {
            param_event.SetEventType(myEVT_WAH_ENABLE);
            param_event.SetEnable(param.enable);
            ProcessWindowEvent(param_event);
            DataSave::NodeAttributesSetValue(preset_node, attr_name_param_enable, param.enable ? "1" : "0");
        }
        break;
    }
}


wxXmlNode *PanelWah::SelectPreset(wxString name)
{
    double filter_freq_width = param.filter_freq_width;
    double speed = param.speed;
    double filter_q = param.filter_q;
    double filter_gain = param.filter_gain;
    double filter_freq_center = param.filter_freq_center;
    bool enable = param.enable;

    wxString str;
    wxXmlNode *child;
    child = root_node->GetChildren();
    while(child)
    {
        if(strcmp(child->GetName().c_str(), name.c_str()) == 0)
        {
            break;
        }
        child = child->GetNext();
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_enable,str))
    {
        int v;
        if(str.ToInt(&v))
        {
            enable = v ? true : false;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_filter_freq_width,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            filter_freq_width = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_speed,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            speed = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_filter_q,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            filter_q = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_filter_gain,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            filter_gain = v;
        }
    }

    if(DataSave::NodeAttributesGetValue(child,attr_name_param_filter_freq_center,str))
    {
        double v;
        if(str.ToDouble(&v))
        {
            filter_freq_center = v;
        }
    }

    SetParamEnable(enable);
    SetParamFilterFreqWidth(filter_freq_width);
    SetParamSpeed(speed);
    SetParamFilterQ(filter_q);
    SetParamFilterGain(filter_gain);
    SetParamFilterFreqCenter(filter_freq_center);

    // if(child == NULL)
    // {
    //     child = new wxXmlNode(wxXML_ELEMENT_NODE,name);
    //     WriteToXML(child);
    //     root_node->AddChild(child);
    // }

    return child;
}

void PanelWah::PresetListClear(void)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Clear();
        preset_node = nullptr;
    }
}

void PanelWah::AddPresetList(const wxString &preset_name)
{
    wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
    if(cmb)
    {
        cmb->Append(preset_name);
    }
}

wxXmlNode *PanelWah::SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same)
{
    wxXmlNode *child = nullptr;
    is_same = 0;
    if((root != nullptr) && (new_preset_name.empty() == false))
    {
        //查找有没有名字相同的预设
        child = root->GetChildren();
        while(child)
        {
            if(strcmp(child->GetName().c_str(), new_preset_name.c_str()) == 0)
            {
                is_same = 1;
                return nullptr;
            }
            child = child->GetNext();
        }
        child = new wxXmlNode(wxXML_ELEMENT_NODE,new_preset_name);
        WriteToXML(child);
        root->AddChild(child);
        wxChoice *cmb = wxDynamicCast(FindWindowById(ID_CHO_PRESET),wxChoice);
        if(cmb)
        {
            cmb->Append(new_preset_name);
        }
    }
    return child;
}

wxXmlNode *PanelWah::WriteToXML(wxXmlNode *node)
{
    if(node)
    {
        DataSave::NodeAttributesSetValue(node, attr_name_param_enable, param.enable ? "1" : "0");
        DataSave::NodeAttributesSetValue(node, attr_name_param_speed, mDoubleToString(param.speed).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_filter_q, mDoubleToString(param.filter_q).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_filter_gain, mDoubleToString(param.filter_gain).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_filter_freq_center, mDoubleToString(param.filter_freq_center).c_str(), true);
        DataSave::NodeAttributesSetValue(node, attr_name_param_filter_freq_width, mDoubleToString(param.filter_freq_width).c_str(), true);
    }
    return node;
}